<script setup>
import { onMounted, reactive, ref, toRefs, watch } from "vue";
import useKonva from "@/composables/useKonva";
import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
import {
  disinfectRoute,
  disinfectCharge,
  disinfectElevator,
} from "@/api/disinfect/map-setting";
import chargeIcon from "@/assets/images/common/charge_icon.png";
import elevatorInside from "@/assets/images/common/elevator_inside.png";
import elevatorOutside from "@/assets/images/common/elevator_outside.png";

// 接收props
const props = defineProps({
  mapId: { type: Number, default: 0 },
  mapUrl: { type: String, default: "" },
});
const { mapId, mapUrl } = toRefs(props);
const emit = defineEmits(["confirmSuccess"]);

// 当前操作状态
// 0:初始化
// 1:绘制路径
// 2:充电点

const contextMenu = reactive({
  status: 0,
  visible: false,
});

// 路径点列表
const pointList = [];

// konva容器
const container = ref();
const {
  stage,
  layer,
  group,
  pointData,
  loading,
  initStage,
  initImage,
  drawPoint,
  previewPoint,
  handlePointData,
  drawPath,
  previewPath,
  handlePathData,
  clearLayer,
  previewCharge,
} = useKonva();

// 右键菜单
function onContextMenu(e) {
  e.evt.preventDefault();
  contextMenu.visible = true;
  const dom = document.getElementById("contextMenu");
  dom.style.display = "";
  dom.style.top = e.evt.offsetY + "px";
  dom.style.left = e.evt.offsetX + "px";
}

const path = {
  begin() {
    contextMenu.visible = false;
    pointList.length = 0;
    layer.value.on("click.path", path.click);
    clearLayer();
    contextMenu.status = 1;
  },
  end() {
    contextMenu.visible = false;
    if (pointList.length < 2) {
      ElMessage({ type: "warning", message: "请绘制至少两个点" });
      return;
    }
    path.confirm();
    layer.value.off("click.path");
    clearLayer();
    contextMenu.status = 0;
  },
  click(e) {
    if (e.evt.button !== 0) return;
    if (contextMenu.visible) return;
    const { x, y } = layer.value.getRelativePointerPosition();
    pointList.push({ x: Number(x.toFixed(2)), y: Number(y.toFixed(2)) });
    drawPath(pointList);
  },
  async confirm() {
    const { value } = await ElMessageBox.prompt("请输入路径名称");
    const { raw, route } = handlePathData(pointList);
    const { message } = await disinfectRoute.create({
      mid: mapId.value,
      name: value,
      raw,
      route,
    });
    ElNotification({ title: "提示", type: "success", message });
    emit("confirmSuccess");
  },
};

function chargeBegin() {
  contextMenu.visible = false;
  contextMenu.status = 2;
  pointData.value.length = 0;
  layer.value.on("click.charge", chargeClick);
  group.value.removeChildren();
}
function chargeEnd() {
  contextMenu.visible = false;
  if (pointData.value.length < 1) {
    ElMessage({ type: "warning", message: "请绘制充电点" });
  } else {
    contextMenu.status = 0;
    layer.value.off("click.charge");
    chargeConfirm();
  }
}
function chargeClick(e) {
  if (e.evt.button !== 0) return;
  if (contextMenu.visible) return;
  const { x, y } = layer.value.getRelativePointerPosition();
  pointData.value.length = 0;
  pointData.value.push({ x, y });
  drawPoint(chargeIcon);
}
async function chargeConfirm() {
  const { x, y, theta } = handlePointData();
  const { value } = await ElMessageBox.prompt("请输入充电点名称");
  const { message } = await disinfectCharge.create({
    mid: mapId.value,
    name: value,
    chargeX: x,
    chargeY: y,
    rtype: "disinfect",
    tiltAngle: theta,
    status: 0,
  });
  ElNotification({ title: "提示", type: "success", message });
  emit("confirmSuccess");
}

function elevatorBegin(type) {
  contextMenu.visible = false;
  if (type === "inside") {
    contextMenu.status = 3;
  } else {
    contextMenu.status = 4;
  }
  pointData.value.length = 0;
  layer.value.on("click.elevator", elevatorClick);
  group.value.removeChildren();
}
function elevatorEnd() {
  contextMenu.visible = false;
  if (pointData.value.length < 1) {
    ElMessage({ type: "warning", message: "请绘制电梯点" });
  } else {
    layer.value.off("click.elevator");
    elevatorConfirm();
  }
}
function elevatorClick(e) {
  if (e.evt.button !== 0) return;
  if (contextMenu.visible) return;
  const { x, y } = layer.value.getRelativePointerPosition();
  pointData.value.length = 0;
  pointData.value.push({ x, y });
  if (contextMenu.status === 3) {
    drawPoint(elevatorInside);
  } else {
    drawPoint(elevatorOutside);
  }
}
async function elevatorConfirm() {
  const { x, y, theta } = handlePointData();
  const id = mapId.value;
  if (contextMenu.status === 3) {
    const { message } = await disinfectElevator.inside({ id, x, y, theta });
    ElNotification({ title: "提示", type: "success", message });
  } else {
    const { message } = await disinfectElevator.outside({ id, x, y, theta });
    ElNotification({ title: "提示", type: "success", message });
  }
  contextMenu.status = 0;
  group.value.removeChildren();
}

// 加载背景图
watch(mapUrl, () => {
  initImage(mapUrl.value);
});

onMounted(() => {
  initStage("stage", container.value.offsetWidth, container.value.offsetHeight);
  stage.value.on("contextmenu", onContextMenu);
  stage.value.on("click.default", () => (contextMenu.visible = false));
});

defineExpose({ previewPath, clearLayer, previewCharge, previewPoint });
</script>

<template>
  <div ref="container" v-loading="loading" class="h-full relative">
    <div id="stage"></div>
    <div
      v-show="contextMenu.visible"
      id="contextMenu"
      class="flex flex-col absolute shadow-2xl bg-white border-gray-200 border border-solid p-2 rounded"
    >
      <el-button v-if="contextMenu.status === 0" @click="path.begin">
        绘制路径
      </el-button>
      <el-button v-if="contextMenu.status === 1" @click="path.end">
        结束绘制
      </el-button>
      <el-button v-if="contextMenu.status === 0" @click="chargeBegin">
        绘制充电点
      </el-button>
      <el-button v-if="contextMenu.status === 2" @click="chargeEnd">
        结束绘制
      </el-button>
      <el-button
        v-if="contextMenu.status === 0"
        @click="elevatorBegin('inside')"
      >
        电梯内点
      </el-button>
      <el-button
        v-if="contextMenu.status === 0"
        @click="elevatorBegin('outside')"
      >
        电梯外点
      </el-button>
      <el-button
        v-if="contextMenu.status === 3 || contextMenu.status === 4"
        @click="elevatorEnd"
      >
        结束绘制
      </el-button>
    </div>
  </div>
</template>

<style scoped>
.el-button + .el-button {
  margin-left: 0;
  margin-top: 12px;
}
</style>
